import GCBlock from "../components/common-components/GCBlock";
import GCState from "./GCState";


export default class StateMachine<T> {

    state: string = '';
    map: { [key: string]: GCState } = {};

    logic: T;

    inTransition: boolean = false;

    getState() {
        return this.map[this.state];
    }

    register(state: GCState) {
        this.map[state.name] = state;
    }

    async setup(name: string) {
        const state = this.map[name];

        GCBlock.block();
        try {
            await (this.logic as any).doTransform('', name);
        } catch (e) {
            cc.error(`doTransform Error: ${e.message}`);
        } finally {
            GCBlock.unblock();
        }

        state.enter(this.logic);
        this.state = name;
    }

    async to(to: string) {
        const fromState = this.map[this.state];
        const toState = this.map[to];

        fromState.exit(this.logic);

        GCBlock.block();
        try {
            await (this.logic as any).doTransform(this.state, to);
        } catch (e) {
            cc.error(`doTransform Error: ${e.message}`);
        } finally {
            GCBlock.unblock();
        }

        this.state = to;
        toState.enter(this.logic);

        cc.log(`状态机转换完成: ${fromState.name} ==> ${toState.name}`);
    }
}
